package cn.xo68.boot.job;

import cn.xo68.boot.job.entity.DistributedLock;
import cn.xo68.boot.job.entity.JobStatus;
import cn.xo68.boot.job.entity.QuartzJob;
import cn.xo68.boot.job.jdbcstore.JobStoreService;
import cn.xo68.boot.job.jdbcstore.lock.DistributedLockManager;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 自定义任务状态监听处理
 * @author wuxie
 * @date 2018-7-10
 */
@Component
public class JobMonitor implements Runnable{

    private static final Logger logger=LoggerFactory.getLogger(JobMonitor.class);

    @Autowired
    private Scheduler scheduler;
    @Autowired
    private JobStoreService jobStoreService;
    @Autowired
    private JobOperateService jobOperateService;
    @Autowired
    private DistributedLockManager distributedLockManager;

    @Override
    public void run() {

        String schedName= null;
        try {
            schedName = scheduler.getSchedulerName();
        } catch (SchedulerException e) {
        }
        String schedInstance= null;
        try {
            schedInstance = scheduler.getSchedulerInstanceId();
        } catch (SchedulerException e) {

        }

        String lockKey="lock:scheduler-job-Monitor:"+schedName;

        DistributedLock lock= distributedLockManager.tryLock(lockKey, schedName+"$"+ schedInstance, 30*1000, 1*1000);
        if(lock==null){
            logger.info("没有申请到锁，lock_key: {}", lockKey);
            return;
        }
        try{
            List<QuartzJob> list=jobStoreService.listBySchedulerName(scheduler.getSchedulerName(),1,99);
            boolean operResult=true;
            for (QuartzJob quartzJob: list){
                switch (JobStatus.parse(quartzJob.getJobStatus())){
                    case WaitRunning:
                        operResult=jobOperateService.add(quartzJob);
                        if(operResult){
                            jobStoreService.update(quartzJob.getJobId(),JobStatus.WaitRunning.getCode(), JobStatus.Running.getCode());
                        }
                        break;
                    case WaitPause:
                        operResult=jobOperateService.pause(quartzJob);
                        if(operResult){
                            jobStoreService.update(quartzJob.getJobId(),JobStatus.WaitPause.getCode(), JobStatus.Pause.getCode());
                        }
                        break;
                    case WaitResume:
                        operResult=jobOperateService.resume(quartzJob);
                        if(operResult){
                            jobStoreService.update(quartzJob.getJobId(),JobStatus.WaitResume.getCode(), JobStatus.Resume.getCode());
                        }
                        break;
                    case WaitRemove:
                        operResult=jobOperateService.remove(quartzJob);
                        if(operResult){
                            jobStoreService.update(quartzJob.getJobId(),JobStatus.WaitRemove.getCode(), JobStatus.Remove.getCode());
                        }
                        break;
                    case WaitTrigger:
                        operResult=jobOperateService.trigger(quartzJob);
                        if(operResult){
                            jobStoreService.update(quartzJob.getJobId(),JobStatus.WaitTrigger.getCode(), JobStatus.Trigger.getCode());
                        }
                        break;
                    default:
                }

            }

        }catch (Exception e){
            logger.error("任务状态监听处理异常", e);
        }finally {
            distributedLockManager.unLock(lock.getLockKey());
        }
    }
}
